package com.example.longimageView.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.Scroller;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.blankj.utilcode.util.LogUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.davemorrissey.labs.subscaleview.ImageSource;
import com.davemorrissey.labs.subscaleview.ImageViewState;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import com.example.longimageView.BuildConfig;
import com.example.longimageView.R;
import com.example.longimageView.utils.ScreenUtils;

import java.util.Random;

/**
 * @author: njb
 * @date: 2023/4/10 20:22
 * @desc:TV端超长巨图加载组件
 */
public class EasyTVLongView extends SubsamplingScaleImageView implements SubsamplingScaleImageView.OnImageEventListener {
    private static final String TAG = "EasyLongViewLog";
    private Scroller mScroller;
    private final int scrollHeight = 200;
    private int scrollY = 0;
    private float defaultScale = 1.0f;
    private boolean isFocus = false;
    private Paint paint = new Paint();
    private PointF vPoint = new PointF();
    private PointF sPoint;
    private Bitmap bitmap;

    public EasyTVLongView(Context context, AttributeSet attr) {
        super(context, attr);
        initBitmap();
        initialise(context);
    }

    public EasyTVLongView(Context context) {
        super(context);
        initBitmap();
        initialise(context);
    }

    private void initialise(Context context) {
        mScroller = new Scroller(context);
        this.setOnFocusChangeListener((v, hasFocus) -> {
            isFocus = hasFocus;
        });
        this.setOnKeyListener((v, keyCode, event) -> {
            setDispatchKeyEvent(event);
            return false;
        });
    }

 /*   @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        setDispatchKeyEvent(event);
        return super.dispatchKeyEvent(event);
    }*/

    public void setDispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) {
                if (isFocus) {
                    startSmoothScrollUp(0, 50);
                }
            }
            if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {
                if (isFocus) {
                    startSmoothScrollDown(0, 50);
                }
            }
        }
       /* if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER) {
                play();
            }
        }*/
    }

    /**
     * 向下滑动
     * @param desX
     * @param ms
     */
    public void startSmoothScrollDown(int desX, int ms) {
        int startX = getScrollX();
        int startY = getScrollY();
        scrollY = getScrollY();
        int scrollDownHeight = this.getSHeight() - scrollY - scrollHeight;
        //startScroll(x起始坐标，y起始坐标，x方向偏移值，y方向偏移值，滚动时长)
        if ((scrollDownHeight + scrollHeight) > ScreenUtils.getScreenHeight(this.getContext())) {
            mScroller.startScroll(startX, startY, desX - startX, scrollHeight, ms);
        }
        if (BuildConfig.DEBUG) {
            LogUtils.d(TAG, "----向下滑动距离---" + scrollDownHeight + "----滑动y坐标----" + startY);
        }
        invalidate();
    }

    /**
     * 向上滑动
     *
     * @param desX
     * @param ms
     */
    public void startSmoothScrollUp(int desX, int ms) {
        int startX = getScrollX();
        int startY = getScrollY();
        scrollY = getScrollY();
        if (BuildConfig.DEBUG) {
            LogUtils.d(TAG, "向上滑动滑动x坐标" + startX + "----滑动y坐标----" + startY);
        }
        if (scrollY > ScreenUtils.dip2px(this.getContext(), 60)) {
            mScroller.startScroll(0, startY, desX, -scrollHeight, ms);
        }
        invalidate();
    }

    /**
     * 加载图片数据
     *
     * @param url
     */
    public void setLongImages(String url) {
        try {
            Glide.with(this.getContext())
                    .asBitmap()
                    .load(url)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .into(new SimpleTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                            EasyTVLongView.this.setImage(ImageSource.cachedBitmap(resource), new ImageViewState(defaultScale, new PointF(0, 0), 0));
                            if (BuildConfig.DEBUG) {
                                LogUtils.d(TAG, "---图片宽度为---- " + resource.getWidth() + "---图片高度为---" + resource.getHeight());
                            }
                            EasyTVLongView.this.onImageLoaded();
                        }

                        @Override
                        public void onDestroy() {
                            super.onDestroy();
                            EasyTVLongView.this.recycle();
                        }
                    });
            EasyTVLongView.this.setFocusable(true);
        } catch (Exception e) {
            e.printStackTrace();
            EasyTVLongView.this.onImageLoadError(e);
        }
    }

    public void play() {
        Random random = new Random();
        if (this.isReady()) {
            float maxScale = this.getMaxScale();
            float minScale = this.getMinScale();
            float scale = (random.nextFloat() * (maxScale - minScale)) + minScale;
            PointF center = new PointF(random.nextInt(this.getSWidth()), random.nextInt(this.getSHeight()));
            this.setPin(center);
            SubsamplingScaleImageView.AnimationBuilder animationBuilder = this.animateScaleAndCenter(scale, center);
            if (this.getSHeight() == 0) {
                if (animationBuilder != null) {
                    animationBuilder.withDuration(2000).withEasing(EASE_OUT_QUAD).withInterruptible(false).start();
                }
            } else {
                if (animationBuilder != null) {
                    animationBuilder.withDuration(500).start();
                }
            }
        }
    }

    public void setPin(PointF sPin) {
        this.sPoint = sPin;
        initBitmap();
        invalidate();
    }

    private void initBitmap() {
        float density = getResources().getDisplayMetrics().densityDpi;
        bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.pushpin_blue);
        float w = (density / 420f) * bitmap.getWidth();
        float h = (density / 420f) * bitmap.getHeight();
        bitmap = Bitmap.createScaledBitmap(bitmap, (int) w, (int) h, true);
    }


    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (!isReady()) {
            return;
        }
        paint.setAntiAlias(true);
        if (sPoint != null && bitmap != null) {
            sourceToViewCoord(sPoint, vPoint);
            float vX = vPoint.x - (bitmap.getWidth() / 2);
            float vY = vPoint.y - bitmap.getHeight();
            canvas.drawBitmap(bitmap, vX, vY, paint);
        }
    }

    @Override
    public void onReady() {
        if (BuildConfig.DEBUG) {
            LogUtils.d(TAG, "图片资源已准备" + this.isReady());
        }
    }

    @Override
    public void onImageLoaded() {
        if (BuildConfig.DEBUG) {
            LogUtils.d(TAG, "图片已加载" + this.isImageLoaded());
        }
    }

    @Override
    public void onPreviewLoadError(Exception e) {
        if (BuildConfig.DEBUG) {
            LogUtils.e(TAG, "图片预览失败" + e.getMessage());
        }
    }

    @Override
    public void onImageLoadError(Exception e) {
        if (BuildConfig.DEBUG) {
            LogUtils.e(TAG, "图片加载失败" + e.getMessage());
        }
    }

    @Override
    public void onTileLoadError(Exception e) {
        if (BuildConfig.DEBUG) {
            LogUtils.e(TAG, "图片平铺加载失败" + e.getMessage());
        }
    }

    @Override
    public void onPreviewReleased() {
        if (BuildConfig.DEBUG) {
            if (this.getDrawingCache() != null) {
                LogUtils.d(TAG, "图片预加载资源已回收" + this.getDrawingCache().isRecycled());
            }
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        this.recycle();
    }
}
